package com.acme.bankapp.service.bank.server;

import com.acme.bankapp.domain.bank.Bank;
import com.acme.bankapp.domain.bank.exceptions.ClientExistsException;
import com.acme.bankapp.service.bank.BankService;
import com.acme.bankapp.service.bank.network.Transport;
import com.acme.bankapp.service.bank.network.TransportException;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class BankServer {
    public void startServer(Bank bank, int port) {
        try (
                ServerSocket providerSocket = new ServerSocket(port, 10);
                Socket connection = providerSocket.accept()) {
            System.out.println("Connection received from " + connection.getInetAddress().getHostName());
            try (Transport transport = new Transport(connection)) {
                String message;
                do {
                    message = transport.receiveMessage();
                    System.out.println("client>" + message);
                    String answer = handleMessage(bank, message);
                    System.out.println("server>" + answer);
                    transport.sendMessage(answer);
                } while (!"bye".equals(message));
            } catch (TransportException ioException) {
                ioException.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private String handleMessage(Bank bank, String message) {
        String[] parsedCommand = parseCommand(message);
        switch (parsedCommand[0]) {
            case "add":
                try {
                    BankService.loadClientsFromString(bank, parsedCommand[1]);
                    return "Client was saved";
                } catch (IOException | ClientExistsException e) {
                    return "Saving failed : reason " + e.getMessage();
                }
            case "get":
                switch (parsedCommand[1]) {
                    case "clients_balance":
                        return BankService.print(bank, BankService.PrintType.BALANCE);
                    case "clients_max_withdraw":
                        return BankService.print(bank, BankService.PrintType.MAX_WITHDRAW);
                    default:
                        return "Unknown get parameter format";
                }
            case "bye":
                return "bye";
            default:
                return "Unknown command";
        }
    }

    private String[] parseCommand(String message) {
        String[] parsedCommand = new String[2];

        int firstSpace = message.indexOf(' ');

        if (firstSpace != -1) {
            parsedCommand[0] = message.substring(0, firstSpace);
            parsedCommand[1] = message.substring(firstSpace + 1);
        } else {
            parsedCommand[0] = message;
            parsedCommand[1] = null;
        }
        return parsedCommand;
    }
}
